using Microsoft.EntityFrameworkCore;
using DeathReportManagement.Data;
using DeathReportManagement.Models;

namespace DeathReportManagement.Services;

public class DeathReportService
{
    private readonly DeathReportContext _context;
    private readonly AuthService _authService;
    private readonly OperationLogService _operationLogService;
    
    public DeathReportService(
        DeathReportContext context, 
        AuthService authService,
        OperationLogService operationLogService)
    {
        _context = context;
        _authService = authService;
        _operationLogService = operationLogService;
    }
    
    public async Task<DeathReport> CreateAsync(DeathReport report)
    {
        var currentUserId = _authService.GetCurrentUserId();
        if (currentUserId == null)
        {
            throw new UnauthorizedAccessException("用户未登录");
        }
        
        report.ReportNo = await GenerateReportNoAsync();
        report.CreateBy = currentUserId.Value;
        report.CreateTime = DateTime.Now;
        
        if (_authService.IsDoctor())
        {
            report.ReportStatus = ReportStatus.SubReported;
        }
        
        _context.DeathReports.Add(report);
        await _context.SaveChangesAsync();
        
        await _operationLogService.LogAsync(report.Id, "创建死亡报告", currentUserId.Value);
        
        if (_authService.IsDoctor())
        {
            await _operationLogService.LogAsync(report.Id, "自动附联上报", currentUserId.Value);
        }
        
        return report;
    }
    
    public async Task<DeathReport?> GetByIdAsync(int id)
    {
        return await _context.DeathReports
            .Include(r => r.Creator)
            .Include(r => r.Updater)
            .Include(r => r.Auditor)
            .FirstOrDefaultAsync(r => r.Id == id);
    }
    
    public async Task<DeathReport?> UpdateAsync(int id, DeathReport report)
    {
        var currentUserId = _authService.GetCurrentUserId();
        if (currentUserId == null)
        {
            throw new UnauthorizedAccessException("用户未登录");
        }
        
        var existingReport = await _context.DeathReports.FindAsync(id);
        if (existingReport == null)
        {
            return null;
        }
        
        if (_authService.IsDoctor() && existingReport.AuditStatus == AuditStatus.Approved)
        {
            throw new InvalidOperationException("已审核的报告不能修改");
        }
        
        UpdateReportFields(existingReport, report);
        existingReport.UpdateBy = currentUserId.Value;
        existingReport.UpdateTime = DateTime.Now;
        
        await _context.SaveChangesAsync();
        await _operationLogService.LogAsync(id, "修改死亡报告", currentUserId.Value);
        
        return existingReport;
    }
    
    public async Task<bool> AuditAsync(int id, bool approved)
    {
        var currentUserId = _authService.GetCurrentUserId();
        if (currentUserId == null || !_authService.IsAdmin())
        {
            throw new UnauthorizedAccessException("无权限执行审核操作");
        }
        
        var report = await _context.DeathReports.FindAsync(id);
        if (report == null)
        {
            return false;
        }
        
        report.AuditStatus = approved ? AuditStatus.Approved : AuditStatus.Pending;
        report.AuditBy = currentUserId.Value;
        report.AuditTime = DateTime.Now;
        
        await _context.SaveChangesAsync();
        await _operationLogService.LogAsync(id, approved ? "审核通过" : "审核退回", currentUserId.Value);
        
        return true;
    }
    
    public async Task<bool> SubReportAsync(int id, ReportSubmissionService? submissionService = null)
    {
        var currentUserId = _authService.GetCurrentUserId();
        if (currentUserId == null)
        {
            throw new UnauthorizedAccessException("用户未登录");
        }
        
        var report = await _context.DeathReports.FindAsync(id);
        if (report == null)
        {
            return false;
        }
        
        if (report.ReportStatus != ReportStatus.NotReported)
        {
            throw new InvalidOperationException("报告状态不允许附联上报");
        }
        
        if (submissionService != null)
        {
            var result = await submissionService.SubmitSubReportAsync(report, currentUserId.Value);
            if (!result.Success)
            {
                throw new InvalidOperationException($"附联上报失败: {result.ErrorMessage}");
            }
        }
        
        report.ReportStatus = ReportStatus.SubReported;
        await _context.SaveChangesAsync();
        await _operationLogService.LogAsync(id, "附联上报", currentUserId.Value);
        
        return true;
    }
    
    public async Task<bool> MainReportAsync(int id, ReportSubmissionService? submissionService = null)
    {
        var currentUserId = _authService.GetCurrentUserId();
        if (currentUserId == null || !_authService.IsAdmin())
        {
            throw new UnauthorizedAccessException("无权限执行主联上报");
        }
        
        var report = await _context.DeathReports.FindAsync(id);
        if (report == null)
        {
            return false;
        }
        
        if (report.ReportStatus != ReportStatus.SubReported)
        {
            throw new InvalidOperationException("必须先附联上报才能主联上报");
        }
        
        if (submissionService != null)
        {
            var result = await submissionService.SubmitMainReportAsync(report, currentUserId.Value);
            if (!result.Success)
            {
                throw new InvalidOperationException($"主联上报失败: {result.ErrorMessage}");
            }
        }
        
        report.ReportStatus = ReportStatus.MainReported;
        await _context.SaveChangesAsync();
        await _operationLogService.LogAsync(id, "主联上报", currentUserId.Value);
        
        return true;
    }
    
    public async Task<List<DeathReport>> GetReportsAsync(
        int? auditStatus = null,
        int? reportStatus = null,
        int? createBy = null,
        int pageIndex = 1,
        int pageSize = 20)
    {
        var query = _context.DeathReports
            .Include(r => r.Creator)
            .Include(r => r.Auditor)
            .AsQueryable();
        
        if (auditStatus.HasValue)
        {
            query = query.Where(r => (int)r.AuditStatus == auditStatus.Value);
        }
        
        if (reportStatus.HasValue)
        {
            query = query.Where(r => (int)r.ReportStatus == reportStatus.Value);
        }
        
        if (createBy.HasValue)
        {
            query = query.Where(r => r.CreateBy == createBy.Value);
        }
        
        if (_authService.IsDoctor())
        {
            var currentUserId = _authService.GetCurrentUserId();
            query = query.Where(r => r.CreateBy == currentUserId);
        }
        
        return await query
            .OrderByDescending(r => r.CreateTime)
            .Skip((pageIndex - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }
    
    private async Task<string> GenerateReportNoAsync()
    {
        var today = DateTime.Today;
        var prefix = $"DR{today:yyyyMMdd}";
        
        var lastReport = await _context.DeathReports
            .Where(r => r.ReportNo.StartsWith(prefix))
            .OrderByDescending(r => r.ReportNo)
            .FirstOrDefaultAsync();
        
        int sequence = 1;
        if (lastReport != null)
        {
            var lastSequence = lastReport.ReportNo.Substring(prefix.Length);
            if (int.TryParse(lastSequence, out int num))
            {
                sequence = num + 1;
            }
        }
        
        return $"{prefix}{sequence:D4}";
    }
    
    private void UpdateReportFields(DeathReport existing, DeathReport updated)
    {
        existing.OutpatientNo = updated.OutpatientNo;
        existing.InpatientNo = updated.InpatientNo;
        existing.HospitalizationCount = updated.HospitalizationCount;
        existing.DeceasedName = updated.DeceasedName;
        existing.IsAnonymous = updated.IsAnonymous;
        existing.Gender = updated.Gender;
        existing.Ethnicity = updated.Ethnicity;
        existing.IdType = updated.IdType;
        existing.IdNumber = updated.IdNumber;
        existing.BirthDate = updated.BirthDate;
        existing.Age = updated.Age;
        existing.AgeUnit = updated.AgeUnit;
        existing.MaritalStatus = updated.MaritalStatus;
        existing.Education = updated.Education;
        existing.PersonalIdentity = updated.PersonalIdentity;
        existing.DeathDateTime = updated.DeathDateTime;
        existing.DeathLocation = updated.DeathLocation;
        existing.IsPregnant = updated.IsPregnant;
        existing.WorkUnit = updated.WorkUnit;
        existing.HouseholdAddressType = updated.HouseholdAddressType;
        existing.HouseholdAddress = updated.HouseholdAddress;
        existing.HouseholdAddressCode = updated.HouseholdAddressCode;
        existing.HouseholdDetailAddress = updated.HouseholdDetailAddress;
        existing.ResidenceAddressType = updated.ResidenceAddressType;
        existing.ResidenceAddress = updated.ResidenceAddress;
        existing.ResidenceDetailAddress = updated.ResidenceDetailAddress;
        existing.ContactName = updated.ContactName;
        existing.ContactPhone = updated.ContactPhone;
        existing.ContactIdType = updated.ContactIdType;
    }
}